# -*- coding: utf-8 -*-
import pandas as pd
from sklearn.linear_model import LogisticRegression
def prepare_and_label(dataset):
    data = dataset.copy()
    data[['discount_rate', 'min_cost_of_manjian']] = data['Discount_rate'].apply(
        lambda x: (lambda val: (
            (float(val.split(':')[0]) - float(val.split(':')[1])) / float(val.split(':')[0]) if ':' in val
            else float(val), int(val.split(':')[0]) if ':' in val else -1)
        )(str(x))
    ).apply(pd.Series)
    data['is_manjian'] = (data['min_cost_of_manjian'] != -1).astype(int)  # 满减标识
    data['Distance'].fillna(-1, inplace=True)
    data['null_distance'] = (data['Distance'] == -1).astype(int)
    data['date_received'] = pd.to_datetime(data['Date_received'], format='%Y%m%d')
    if 'Date' in data.columns:
        data['date'] = pd.to_datetime(data['Date'], format='%Y%m%d')
    if 'Date' in data.columns:
        data['label'] = ((data['date'] - data['date_received']).dt.days <= 15).astype(int)
    return data
def get_simple_feature(label_field):
    data = label_field.copy()
    data['Coupon_id'] = data['Coupon_id'].map(int)  # 转换为int类型
    data['Date_received'] = data['Date_received'].map(int)  
    data['cnt'] = 1  # 方便特征提取
    feature = data.copy()
    def group_feature(keys, prefix, agg_func, agg_lambda=None):
        group = data.groupby(keys)['cnt'].agg(agg_lambda if agg_lambda else agg_func).reset_index()
        group = group.rename(columns={'cnt': prefix + agg_func})
        return pd.merge(feature, group, on=keys, how='left')
    feature = group_feature(['User_id'], 'simple_User_id_', 'count')
    feature = group_feature(['User_id', 'Coupon_id'], 'simple_User_id_Coupon_id_', 'count')
    feature = group_feature(['User_id', 'Date_received'], 'simple_User_id_Date_received_', 'count')
    feature = group_feature(['User_id', 'Coupon_id', 'Date_received'], 'simple_User_id_Coupon_id_Date_received_', 'count')
    feature = group_feature(['User_id', 'Coupon_id', 'Date_received'], 'simple_User_id_Coupon_id_Date_received_', 'repeat_receive', lambda x: 1 if len(x) > 1 else 0)
    feature.drop(['cnt'], axis=1, inplace=True)
    return feature
def get_dataset(history_field, middle_field, label_field):
    week_feat = get_week_feature(label_field)  # 日期特征
    simple_feat = get_simple_feature(label_field)  # 示例简单特征
    share_characters = list(set(simple_feat.columns) & set(week_feat.columns))  # 共有属性
    dataset = pd.concat([week_feat, simple_feat.drop(share_characters, axis=1)], axis=1)
    drop_columns = ['Merchant_id', 'Discount_rate', 'Date', 'date_received', 'date'] if 'Date' in dataset else ['Merchant_id', 'Discount_rate', 'date_received']
    dataset.drop(columns=drop_columns, inplace=True)
    if 'label' in dataset.columns:
        label = dataset.pop('label')
        dataset['label'] = label
    for col in ['User_id', 'Coupon_id', 'Date_received', 'Distance']:
        dataset[col] = dataset[col].astype(int)
    if 'label' in dataset.columns:
        dataset['label'] = dataset['label'].astype(int)
    dataset.drop_duplicates(keep='first', inplace=True)
    dataset.reset_index(drop=True, inplace=True)
    return dataset
def get_week_feature(label_field):
    data = label_field.copy()
    data['Coupon_id'] = data['Coupon_id'].astype('Int64')  # 处理为整型，避免空值影响
    data['Date_received'] = data['Date_received'].astype('Int64')  # 处理为整型，避免空值影响
    data['week'] = pd.to_datetime(data['Date_received'], errors='coerce').dt.weekday
    data['is_weekend'] = data['week'].isin([5, 6]).astype(int)  # 周末为1，其他为0
    week_dummies = pd.get_dummies(data['week'], prefix='week')
    data = pd.concat([data, week_dummies], axis=1)
    data.reset_index(drop=True, inplace=True)
    return data
def model_lr(train, test):
    X_train = train.drop(['User_id', 'Coupon_id', 'Date_received', 'label'], axis=1)
    y_train = train['label']
    X_test = test.drop(['User_id', 'Coupon_id', 'Date_received'], axis=1)
    model = LogisticRegression(solver='liblinear', max_iter=1000)
    model.fit(X_train, y_train)
    predict = model.predict_proba(X_test)[:, 1]
    predict = pd.DataFrame(predict, columns=['prob'])
    result = pd.concat([test[['User_id', 'Coupon_id', 'Date_received']], predict], axis=1)
    return result
date_ranges = {
    'train': [('2016/3/2', 60), ('2016/5/1', 15), ('2016/5/16', 31)],
    'validate': [('2016/1/16', 60), ('2016/3/16', 15), ('2016/3/31', 31)],
    'test': [('2016/4/17', 60), ('2016/6/16', 15), None]  # None表示标签区间没有特定日期范围
}
def get_date_range_data(data, start_date, periods):
    return data[data['date_received'].isin(pd.date_range(start_date, periods=periods))]
def split_data(data, date_ranges):
    fields = {}
    for label, ranges in date_ranges.items():
        history_start, history_period = ranges[0]
        middle_start, middle_period = ranges[1]
        label_start, label_period = ranges[2] if ranges[2] else (None, None)
        history_field = get_date_range_data(data, history_start, history_period)
        middle_field = get_date_range_data(data, middle_start, middle_period)
        label_field = data[data['date_received'].isin(pd.date_range(label_start, periods=label_period))] if label_start else data.copy()
        fields[f'{label}_history_field'] = history_field
        fields[f'{label}_middle_field'] = middle_field
        fields[f'{label}_label_field'] = label_field
    return fields
if __name__ == '__main__':
    off_train = pd.read_csv(r'C:\Users\16226\Desktop\ccf_offline_stage1_train.csv')
    off_test = pd.read_csv(r'C:\Users\16226\Desktop\ccf_offline_stage1_test_revised.csv')
    off_train = prepare_and_label(off_train)
    off_test = prepare_and_label(off_test)
    fields = split_data(off_train, date_ranges)
    fields['test_label_field'] = off_test.copy()
    train_history_field = fields['train_history_field']
    train_middle_field = fields['train_middle_field']
    train_label_field = fields['train_label_field']
    validate_history_field = fields['validate_history_field']
    validate_middle_field = fields['validate_middle_field']
    validate_label_field = fields['validate_label_field']
    test_history_field = fields['test_history_field']
    test_middle_field = fields['test_middle_field']
    test_label_field = fields['test_label_field']  
    result = {
        'train': {'history': train_history_field, 'middle': train_middle_field, 'label': train_label_field},
        'validate': {'history': validate_history_field, 'middle': validate_middle_field, 'label': validate_label_field},
        'test': {'history': test_history_field, 'middle': test_middle_field, 'label': test_label_field}}
    train = get_dataset(train_history_field, train_middle_field, train_label_field)
    validate = get_dataset(validate_history_field, validate_middle_field, validate_label_field)
    test = get_dataset(test_history_field, test_middle_field, test_label_field)
    big_train = pd.concat([train, validate], axis=0)
    result= model_lr(big_train, test)
    result.to_csv(r'C:\Users\16226\Desktop\output_files\easy.csv', index=False, header=None)






































